﻿using My.Domain.Shared.Issues.Events;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Volo.Abp;
using Volo.Abp.Auditing;
using Volo.Abp.Domain.Entities;
using Volo.Abp.Timing;

namespace My.Domain.Issues
{
    /// <summary>
    /// 问题的领域
    /// </summary>
    public class Issue : BasicAggregateRoot<Guid>, IHasCreationTime
    {
        private Issue()
        {

        }

        public Issue(Guid id, Guid repositoryId, string title, string? text = null, Guid? assignedUserId = null) : base(id)
        {
            Check.NotNull(id, nameof(id));
            RepositoryId = repositoryId;
            SetTitle(title);
            Text = text;
            AssignedUserId = assignedUserId;
            Comments = new List<Comments.Comment>();
            IssueLabels = new List<IssueLabels.IssueLabel>();
        }

        public string Title { get; private set; }//需要验证，不允许直接修改

        public string? Text { get; set; }//No validation

        public bool IsLocked { get; private set; }//有业务逻辑的

        public bool IsClosed { get; private set; }//Should change with CloseReason

        public EnumCloseReason? CloseReason { get; private set; }//Should change with IsClosed

        public DateTime? CloseDate { get; private set; }

        /// <summary>
        /// 仓库(领域)的Id
        /// </summary>
        public Guid RepositoryId { get; private set; }//不允许被修改

        /// <summary>
        /// 用户(领域)的Id
        /// </summary>
        public Guid? AssignedUserId { get; internal set; }//No validation

        /// <summary>
        /// 创建时间
        /// </summary>
        public DateTime CreationTime { get; private set; }

        /// <summary>
        /// 最后评论的时间
        /// </summary>
        public DateTime? LastCommentTime { get; private set; }

        /// <summary>
        /// 问题的所有评论
        /// </summary>
        public ICollection<Comments.Comment> Comments { get; set; }

        /// <summary>
        /// 问题的所有标签id
        /// </summary>
        public ICollection<IssueLabels.IssueLabel> IssueLabels { get; set; }

        /// <summary>
        /// 添加评论
        /// </summary>
        public void AddComment(Guid id, Guid userId, string text)
        {
            Comments.Add(new Domain.Comments.Comment(id, text, userId));
            LastCommentTime = DateTime.Now;
        }

        public void SetTitle(string title)
        {
            Title = Check.NotNullOrWhiteSpace(title, nameof(title));
        }

        /// <summary>
        /// 关闭问题
        /// </summary>
        public void Close(EnumCloseReason reason)
        {
            IsClosed = true;
            CloseReason = reason;
            CloseDate = DateTime.UtcNow;
            AddLocalEvent(new IssueCloseEvent { IssueId = Id });
        }

        /// <summary>
        /// 重新打开
        /// </summary>
        public void ReOpen()
        {
            if (!IsClosed)
            {
                return;
            }

            if (IsLocked)
            {
                throw new UserFriendlyException("问题已经被锁定，无法重新打开");
            }

            IsClosed = false;
            CloseReason = null;
            CloseDate = null;
            AddDistributedEvent(new IssueReOpenEto { IssueId = Id });
        }

        /// <summary>
        /// 锁住问题
        /// </summary>
        public void Lock()
        {
            if (!IsClosed)
            {
                throw new UserFriendlyException("无法锁定已打开的问题");
            }

            IsLocked = true;
        }

        /// <summary>
        /// 解锁问题
        /// </summary>
        public void UnLock()
        {
            IsLocked = false;
        }

        /// <summary>
        /// 是否非活动
        /// </summary>
        /// <returns></returns>
        public bool IsInActive()
        {
            //var daysAgo30 = DateTime.Now.Subtract(TimeSpan.FromDays(30));
            //return
            //    //Open
            //    !IsClosed &&

            //    //Assigned to nobody
            //    AssignedUserId == null &&

            //    //Created 30+ days ago
            //    CreationTime < daysAgo30 &&

            //    //No comment or the last comment was 30+ days ago
            //    (LastCommentTime == null || LastCommentTime < daysAgo30);
            return new InActiveIssueSpecification().IsSatisfiedBy(this);
        }
    }

    public enum EnumCloseReason : byte
    {
        Normal = 1,
    }
}
